//#include<iostream>
//using namespace std;
//class A
//{
//public:
//	void f() { cout << "A::f()" << endl; }
//	int a;
//};
//class B : public A
//{
//public:
//	void f(int a) { cout << "B::f()" << endl; }
//	int a;
//};
//int main()
//{
//	B b;
//	b.f();
//	return 0;
//}
//#include<iostream>
//using namespace std;
//class A
//{
//public:
//	A(int a = 0, int b = 0)
//		:_a(a)
//		,_b(b)
//	{
//		cout << "A()" << endl;
//	}
//	~A()
//	{
//		cout << "~A()" << endl;
//	}
//protected:
//	int _a;
//	int _b;
//};
//class B : public A
//{
//public:
//	B(int c = 0)
//		:_c(c)
//	{
//		cout << "B()" << endl;
//	}
//	~B()
//	{
//		cout << "~B()" << endl;
//	}
//private:
//	int _c;
//};
//int main()
//{
//	B b(10);
//	return 0;
//}
#include<iostream>
using namespace std;
template<class T1, class T2>
class Data
{
public:
	Data() { cout << "Data<T1, T2>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};
template <class T1>
class Data<T1, int>
{
public:
	Data() { cout << "Data<T1, int>" << endl; }
private:
	T1 _d1;
	int _d2;
};
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:
	Data() { cout << "Data<T1*, T2*>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:
	Data(const T1& d1, const T2& d2)
		: _d1(d1)
		, _d2(d2)
	{
		cout << "Data<T1&, T2&>" << endl;
	}
private:
	const T1& _d1;
	const T2& _d2;
};
int main()
{
	Data<double, int> d1;
	Data<int, double> d2;
	Data<int*, int*> d3;
	Data<int&, int&> d4(1, 2);
	return 0;
}